package org.linlinjava.litemall.wx.aiweb;

import com.alibaba.fastjson.JSONObject;
import jodd.util.CollectionUtil;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.linlinjava.litemall.core.util.JacksonUtil;
import org.linlinjava.litemall.core.util.ResponseUtil;
import org.linlinjava.litemall.db.domain.LemonlaSession;
import org.linlinjava.litemall.db.domain.LemonlaUserPoint;
import org.linlinjava.litemall.db.service.LemonlaSessionService;
import org.linlinjava.litemall.db.service.LemonlaUserPointService;
import org.linlinjava.litemall.wx.annotation.LoginUser;
import org.linlinjava.litemall.wx.service.ChatGPTService;
import org.linlinjava.litemall.wx.util.ChatUtil;
import org.linlinjava.litemall.wx.util.ContentValidateUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;

import static org.linlinjava.litemall.wx.util.WxResponseCode.LACK_POINT;

@RestController
@RequestMapping("/wx/ai/chat")
@Validated
public class WxAiChatController {


    private final Log logger = LogFactory.getLog(WxAiChatController.class);
    @Autowired
    private LemonlaSessionService sessionService;
    @Autowired
    private ChatGPTService gptService;
    @Autowired
    private LemonlaUserPointService userPointService;
    /**
     * 开启一个新的会话
     * <p>
     *
     *
     * @param userId 用户ID
     * @param body   请求内容，{actorId: xxx, nickname: xxx, scene: xxx }
     * @return 会话场景信息
     */
    @PostMapping("start")
    public Object startSession(@LoginUser Integer userId, @RequestBody String body){
        if (userId == null) {
            return ResponseUtil.unlogin();
        }

        Integer actorId = JacksonUtil.parseInteger(body, "actorId");
        String scene = JacksonUtil.parseString(body, "scene");

        String nickname = JacksonUtil.parseString(body, "nickname");
        Integer sex = JacksonUtil.parseInteger(body, "sex"); // 1男， 2 女
        if (actorId==null&&nickname==null&&sex==null) {
            return ResponseUtil.badArgument();
        }

        if (actorId==null) {
            if (sex == 1) {
                actorId = 100001;
            } else {
                actorId = 100000;
            }
        }
        //检查是否有未关闭的session
        final List<LemonlaSession> lemonlaSessions = sessionService.queryActive(userId,actorId);
        if (!lemonlaSessions.isEmpty()) {
            for (LemonlaSession lemonlaSession : lemonlaSessions) {
                lemonlaSession.setStatus((byte) 2);
                sessionService.updateById(lemonlaSession);
            }
        }

        LemonlaSession session=new LemonlaSession();
        session.setActorId(actorId);
        session.setSceneInformation(scene);
        session.setUserId(userId);
        session.setNickname(nickname);
        sessionService.add(session);

        return ResponseUtil.ok(session);
    }

    /**
     * 关闭一个会话
     * <p>
     *
     *
     * @param userId 用户ID
     * @param body   请求内容，{sessionId: xxx}
     * @return 操作结果
     */
    @PostMapping("end")
    public Object endSession(@LoginUser Integer userId, @RequestBody String body){
        if (userId == null) {
            return ResponseUtil.unlogin();
        }

        Integer actorId = JacksonUtil.parseInteger(body, "actorId");
        if (!ObjectUtils.allNotNull(actorId)) {
            return ResponseUtil.badArgument();
        }
        //检查是否有未关闭的session
        final List<LemonlaSession> lemonlaSessions = sessionService.queryActive(userId,actorId);
        if (lemonlaSessions.isEmpty()) {
            logger.warn("没有找到可关闭的会话信息 userId = "+userId + " actorId = "+actorId);
        }else {
            for (LemonlaSession lemonlaSession : lemonlaSessions) {
                lemonlaSession.setStatus((byte) 1);
                sessionService.updateById(lemonlaSession);
            }
        }
        return ResponseUtil.ok();
    }

    /**
     * 发送消息
     * <p>
     *
     *
     * @param userId 用户ID
     * @param body   请求内容，{sessionId: xxx,content: xxx}
     * @return 操作结果
     */
    @PostMapping("send")
    public Object sendMessage(@LoginUser Integer userId, @RequestBody String body){
        if (userId == null) {
            return ResponseUtil.unlogin();
        }

        Integer sessionId = JacksonUtil.parseInteger(body, "sessionId");
        String  content = JacksonUtil.parseString(body, "content");
        if (!ObjectUtils.allNotNull(sessionId)) {
            return ResponseUtil.badArgument();
        }
        //检查是否有未关闭的session
        final LemonlaSession session = sessionService.query(sessionId);
        if (session==null || !userId.equals(session.getUserId())) {
            return ResponseUtil.noSessionFound();
        }
        LemonlaUserPoint point = userPointService.findByUserId(userId);
        if (point==null) {
            userPointService.pointForRegister(userId);
        }else if (point.getPoint()<=0) {
            return ResponseUtil.fail(LACK_POINT,"用户积分不足");
        }

        String response = "";
        final boolean valid = ContentValidateUtil.isValid(content);
        if (valid){
         //发送chatgpt进行对话
            response = gptService.chat(session,content);

        }else {
            final Integer hp = session.getHp();
            session.setErrorMessage(session.getErrorMessage()+" / "+content);
            if (hp<=1) {
                logger.warn("对话结束 "+session +" ***** " + content);
                session.setHp(0);
                session.setStatus((byte) 2);
                sessionService.updateById(session);
                response = ChatUtil.terminate();
            }else {
                logger.warn("对话异常 "+session+" ***** " + content);
                session.setHp(hp-1);
                sessionService.updateById(session);
                response = ChatUtil.abnormal();
            }
        }
        Map<String, Object> entity = new HashMap<>();
        entity.put("session",session);
        entity.put("response",response);
        return ResponseUtil.ok(entity);
    }

    /**
     * 发送单次消息
     * <p>
     *
     *
     * @param userId 用户ID
     * @param body   请求内容，{actorId: xxx,params: {"name":"王小美","title":"春晓"}}
     * @return 操作结果
     */
    @PostMapping("sendOnce")
    public Object sendOnce(@LoginUser Integer userId, @RequestBody String body){
        if (userId == null) {
            return ResponseUtil.unlogin();
        }

        Integer actorId = JacksonUtil.parseInteger(body, "actorId");
        String  params = JacksonUtil.parseString(body, "params");
        Integer  sessionId = JacksonUtil.parseInteger(body, "sessionId");
        JSONObject paramObj  = JSONObject.parseObject(params);

        LemonlaUserPoint point = userPointService.findByUserId(userId);
        if (point==null) {
            userPointService.pointForRegister(userId);
        }else if (point.getPoint()<=0) {
            return ResponseUtil.fail(LACK_POINT,"用户积分不足");
        }

        String response = "";
        final boolean valid = ContentValidateUtil.isValid(params);
        if (valid) {
            LemonlaSession session;
            if (sessionId!=null) {
                session = sessionService.query(sessionId);
            }else {
                //创建一个session
                session = new LemonlaSession();
                session.setActorId(actorId);
                session.setUserId(userId);
                sessionService.add(session);
            }
            response = gptService.chatOnce(session, paramObj);
            Map<String, Object> entity = new HashMap<>();
            entity.put("session",session);
            entity.put("response",response);
            return ResponseUtil.ok(entity);
            
           
        } else {
            return ResponseUtil.fail();
        }
    }
}
